home *** CD-ROM | disk | FTP | other *** search
/ PC PowerPlay 22 / PCPP #22.iso / Quake2 / q2source_12_11 / utils3 / qe4 / csg.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-02  |  2.9 KB  |  148 lines

  1.  
  2. #include "qe3.h"
  3.  
  4. /*
  5. ==============
  6. CSG_SplitBrushByFace
  7.  
  8. The incoming brush is NOT freed.
  9. The incoming face is NOT left referenced.
  10. ==============
  11. */
  12. void CSG_SplitBrushByFace (brush_t *in, face_t *f, brush_t **front, brush_t **back)
  13. {
  14.     brush_t    *b;
  15.     face_t    *nf;
  16.     vec3_t    temp;
  17.  
  18.     b = Brush_Clone (in);
  19.     nf = Face_Clone (f);
  20.  
  21.     nf->texdef = b->brush_faces->texdef;
  22.     nf->next = b->brush_faces;
  23.     b->brush_faces = nf;
  24.  
  25.     Brush_Build( b );
  26.     Brush_RemoveEmptyFaces ( b );
  27.     if ( !b->brush_faces )
  28.     {    // completely clipped away
  29.         Brush_Free (b);
  30.         *back = NULL;
  31.     }
  32.     else
  33.     {
  34.         Entity_LinkBrush (in->owner, b);
  35.         *back = b;
  36.     }
  37.  
  38.     b = Brush_Clone (in);
  39.     nf = Face_Clone (f);
  40.     // swap the plane winding
  41.     VectorCopy (nf->planepts[0], temp);
  42.     VectorCopy (nf->planepts[1], nf->planepts[0]);
  43.     VectorCopy (temp, nf->planepts[1]);
  44.  
  45.     nf->texdef = b->brush_faces->texdef;
  46.     nf->next = b->brush_faces;
  47.     b->brush_faces = nf;
  48.  
  49.     Brush_Build( b );
  50.     Brush_RemoveEmptyFaces ( b );
  51.     if ( !b->brush_faces )
  52.     {    // completely clipped away
  53.         Brush_Free (b);
  54.         *front = NULL;
  55.     }
  56.     else
  57.     {
  58.         Entity_LinkBrush (in->owner, b);
  59.         *front = b;
  60.     }
  61. }
  62.  
  63. /*
  64. =============
  65. CSG_MakeHollow
  66. =============
  67. */
  68. void CSG_MakeHollow (void)
  69. {
  70.     brush_t        *b, *front, *back, *next;
  71.     face_t        *f;
  72.     face_t        split;
  73.     vec3_t        move;
  74.     int            i;
  75.  
  76.     for (b = selected_brushes.next ; b != &selected_brushes ; b=next)
  77.     {
  78.         next = b->next;
  79.         for (f = b->brush_faces ; f ; f=f->next)
  80.         {
  81.             split = *f;
  82.             VectorScale (f->plane.normal, g_qeglobals.d_gridsize, move);
  83.             for (i=0 ; i<3 ; i++)
  84.                 VectorSubtract (split.planepts[i], move, split.planepts[i]);
  85.  
  86.             CSG_SplitBrushByFace (b, &split, &front, &back);
  87.             if (back)
  88.                 Brush_Free (back);
  89.             if (front)
  90.                 Brush_AddToList (front, &selected_brushes);
  91.         }
  92.         Brush_Free (b);
  93.     }
  94.     Sys_UpdateWindows (W_ALL);
  95. }
  96.  
  97.  
  98. /*
  99. =============
  100. CSG_Subtract
  101. =============
  102. */
  103. void CSG_Subtract (void)
  104. {
  105.     brush_t        *b, *s, *frag, *front, *back, *next, *snext;
  106.     face_t        *f;
  107.     int            i;
  108.  
  109.     Sys_Printf ("Subtracting...\n");
  110.  
  111.     for (b = selected_brushes.next ; b != &selected_brushes ; b=next)
  112.     {
  113.         next = b->next;
  114.  
  115.         if (b->owner->eclass->fixedsize)
  116.             continue;    // can't use texture from a fixed entity, so don't subtract
  117.  
  118.         for (s=active_brushes.next ; s != &active_brushes ; s=snext)
  119.         {
  120.             snext = s->next;
  121.             if (s->owner->eclass->fixedsize)
  122.                 continue;
  123.  
  124.             for (i=0 ; i<3 ; i++)
  125.                 if (b->mins[i] >= s->maxs[i] - ON_EPSILON 
  126.                 || b->maxs[i] <= s->mins[i] + ON_EPSILON)
  127.                     break;
  128.             if (i != 3)
  129.                 continue;    // definately don't touch
  130.  
  131.             frag = s;
  132.             for (f = b->brush_faces ; f && frag ; f=f->next)
  133.             {
  134.                 CSG_SplitBrushByFace (frag, f, &front, &back);
  135.                 Brush_Free (frag);
  136.                 frag = back;
  137.                 if (front)
  138.                     Brush_AddToList (front, &active_brushes);
  139.             }
  140.             if (frag)
  141.                 Brush_Free (frag);
  142.         }
  143.     }
  144.  
  145.     Sys_Printf ("done.\n");
  146.     Sys_UpdateWindows (W_ALL);
  147. }
  148.